package setting

import (
	"fmt"
	gogrpc "gin-demo/pkg/grpc"
	"github.com/gin-gonic/gin"
	"log"
	"path/filepath"
	"time"

	"github.com/go-ini/ini"
)

const (
	WindowsOS                 = "windows"
	ManyVideoRecordsSingleWay = 1 // 单路录制
	ManyVideoRecordsDoubleWay = 2 // 双路录制
	ManyVideoRecordsMultiWay  = 3 // 三路录制
)

type App struct {
	JwtSecret          string
	PageSize           int
	PrefixUrl          string
	RemoteUrl          string
	CorrectorUrl       string
	Version            string
	LiteUrl            string
	LiteUploadUser     string
	LiteUploadUserPass string

	RuntimeRootPath string

	ImageSavePath  string
	ImageMaxSize   int
	ImageAllowExts []string

	ExportSavePath string
	FontSavePath   string

	LogSavePath       string
	CaseParserLogPath string
	LogSaveName       string
	LogFileExt        string
	TimeFormat        string
	ConfPath          string

	ProfileEnable   bool
	ProfileSavePath string

	CaseRootPath        string
	CasePrintReportPath string

	FeatureLedgeSavePath  string
	FeatureLedgeMaxSize   int64
	FeatureLedgeMaxLen    int
	FeatureLedgeAllowExts []string
	KlArchivedSavePath    string
	KlArchivedExts        []string

	UseDeviceInfoCache bool
}

var AppSetting = &App{}

type Server struct {
	RunMode          string
	DoNotSendSms     bool
	StartClient      bool
	SkipAuth         bool
	OutputDebug      bool
	ClientPath       string
	HttpPort         int
	ReadTimeout      time.Duration
	WriteTimeout     time.Duration
	DeployAloneMode  int
	ManyVideoRecords int
	TcpPort          int
}

var ServerSetting = &Server{}

type Database struct {
	Type        string
	User        string
	Host        string
	Port        int
	Name        string
	TablePrefix string
	LogMode     bool
}

var DatabaseSetting = &Database{}

type Redis struct {
	Host          string
	User          string
	Password      string
	DbName        int
	MaxIdle       int
	MaxActive     int
	MaxActiveWait bool
	IdleTimeout   time.Duration
}

var RedisSetting = &Redis{}

type Aliyun struct {
	AccessKeyID     string
	AccessKeySecret string
	SMSSign         string
}

var AliyunSetting = &Aliyun{}

var StaticsSetting = &Statics{}

type Statics struct {
	StaticPath                  string
	FeatureLegendFile           string
	SectionListCode             string
	SectionFeatureUnusualCode   string
	SyndromeClassListCode       string
	SyndromeFeatureOptFile      string
	KnowledgeVersionList        string
	ScreeningPartsFile          string
	ScreeningPartsAllFile       string
	AssessScreeningPartsFile    string
	AssessScreeningPartsAllFile string
	WindowsToolKitsDLL          string
	AiLabelFile                 string
	SysLabelFile                string
}

var PluginsConfig = &gogrpc.Config{}

var DeviceManageSetting = &DeviceManage{}

type DeviceManage struct {
	DeviceServerScheme   string
	DeviceServerPort     string
	DeviceServerUser     string
	DeviceServerPassword string
}

var CaseBackupSetting = &CaseBackup{}

type CaseBackup struct {
	CaseSaveDisk      string
	CaseBackupDisk    string
	CaseSaveDir       string
	CaseSizeOfDay     int
	CaseSize4Notice   int
	CaseSizeUseOfDay  int
	BaseBackupSkipDay int32
	MinBackupSize     int
	MinSaveSize       int
	CaseBackupEnable  bool
}

var EsSetting = &Es{}

type Es struct {
	EsAddresses           []string
	EsUsername            string
	EsPassword            string
	EsHealthCheckInterval time.Duration
	EsRequestTimeout      time.Duration
}

var cfg *ini.File

const (
	CharStr   = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	NumberStr = "123456789"
)

var RunMode string

func InitSetUp() {
	var err error
	// 设置环境类型方式
	cfg, err = ini.Load("conf/app.ini")
	if err != nil {
		log.Fatalf("setting.Setup, fail to parse 'conf/app.ini': %v", err)
	}
	RunMode = cfg.Section("").Key("RunMode").String()
	gin.SetMode(RunMode) // 设置模式，有三种模式：debug release test
	fmt.Println("已开启模式：", gin.Mode())
	cfg, err = ini.Load(fmt.Sprintf("conf/app_%s.ini", gin.Mode()))
	if err != nil {
		log.Fatalf("setting.Setup, fail to parse 'conf/app_%s.ini': %v", gin.Mode(), err)
	}
}

// Setup initialize the configuration instance
func SetupConfig() {
	InitSetUp()

	mapTo("app", AppSetting)
	mapTo("server", ServerSetting)
	mapTo("database", DatabaseSetting)
	mapTo("redis", RedisSetting)
	mapTo("statics", StaticsSetting)
	mapTo("lpm_plugins_windows", PluginsConfig)
	mapTo("device_manage", DeviceManageSetting)
	mapTo("backup_manage", CaseBackupSetting)
	mapTo("elasticsearch", EsSetting)

	AppSetting.ImageMaxSize = AppSetting.ImageMaxSize * 1024 * 1024
	ServerSetting.ReadTimeout = ServerSetting.ReadTimeout * time.Second
	ServerSetting.WriteTimeout = ServerSetting.ReadTimeout * time.Second
	AliyunSetting.AccessKeyID = "LTAIqCCjg4m8cQMS"
	AliyunSetting.AccessKeySecret = "SzQByRoAYU4yDvSXIqo6Y5PJtnIels"
	AliyunSetting.SMSSign = "广州爱孕记"
	ServerSetting.RunMode = RunMode
}

// mapTo map section
func mapTo(section string, v interface{}) {
	err := cfg.Section(section).MapTo(v)
	if err != nil {
		log.Fatalf("Cfg.MapTo RedisSetting err: %v", err)
	}
}

// IsServerDebug debug
func IsServerDebug() bool {
	return ServerSetting.RunMode == "debug"
}

// IsOutputDebug debug
func IsOutputDebug() bool {
	return ServerSetting.OutputDebug
}

// VideoRecords 录制n路视频，最少1路，最多3路
func VideoRecords() int {
	switch {
	case ServerSetting.ManyVideoRecords <= ManyVideoRecordsSingleWay:
		return ManyVideoRecordsSingleWay
	case ServerSetting.ManyVideoRecords > ManyVideoRecordsMultiWay:
		return ManyVideoRecordsMultiWay
	default:
		return ServerSetting.ManyVideoRecords
	}
}

// GetProfileFilePath get the profile file save path
func GetProfileFilePath() string {
	return filepath.Join(AppSetting.RuntimeRootPath, AppSetting.ProfileSavePath)
}
